<template>
  <div class="vue-container">
    <common-form
      ref="commonForm"
      :disabled="disabled"
      :options="options"
      @handlerClick="handlerClick"
      @advancedSearch="getList"
    />
    <common-table
      ref="table"
      :table-data="data"
      :columns="columns"
      :table-tree="true"
      :lazy="true"
      :load="load"
      :height="height"
      :loading="loading"
    >
      <!-- 部门状态 #1：正常, 2：禁用 -->
      <template #status="scope">
        <el-popconfirm
          v-permission="{ permission: 'system:department:update', disabled }"
          :title="scope.row.status === 1 ? '确定要禁用该部门吗？' : '确定要启用该部门吗？'"
          icon=""
          @confirm="popConfirm(scope.row)"
        >
          <el-switch
            slot="reference"
            v-model="scope.row.status"
            v-permission="{ permission: 'system:department:update', disabled }"
            :active-value="1"
            :inactive-value="2"
            @change="switchChange($event, scope.row)"
          />
        </el-popconfirm>
      </template>
      <!-- 创建时间 -->
      <template #createTime="scope">
        {{ scope.row.createTime | formatTime }}
      </template>
      <!-- 列表操作按钮 -->
      <template #operation="scope">
        <el-button
          v-throttle
          v-permission="'system:department:create'"
          :size="size"
          type="text"
          icon="el-icon-plus"
          @click.stop="handlerRowSave(scope.row)"
        >新增</el-button>
        <el-button
          v-throttle
          v-permission="'system:department:update'"
          :size="size"
          type="text"
          icon="el-icon-edit-outline"
          @click.stop="handlerSave(scope.row)"
        >编辑</el-button>
        <el-button
          v-throttle
          v-permission="'system:department:del'"
          :size="size"
          type="text"
          icon="el-icon-delete"
          class="danger-btn"
          @click.stop="handlerDel(funs['del'], { ...scope.row, ...{ endParentId: scope.row.parentId } })"
        >删除</el-button>
      </template>
    </common-table>
    <!-- 新增or编辑组件 -->
    <add-or-update ref="addOrUpdate" :obj="{ statusList, arr }" @ok="getList" />
  </div>
</template>
<script>
import { mixin } from '@/views/pages/mixin'
import AddOrUpdate from './components/save'
export default {
  name: 'Department',
  components: {
    AddOrUpdate
  },
  mixins: [mixin],
  data() {
    const remote = this.$store.state.settings.funs['list']
    return {
      // 状态数组
      statusList: [],
      // 是否分页
      isPage: false,
      // 表头数组
      columns: [
        {
          prop: 'name',
          align: 'left',
          width: '260',
          label: '部门名称'
        },
        {
          prop: 'status',
          align: 'center',
          type: 'slot',
          slotType: 'status',
          label: '部门状态'
        },
        {
          prop: 'sort',
          align: 'center',
          label: '排序'
        },
        {
          prop: 'remarks',
          align: 'center',
          label: '部门备注'
        },
        {
          prop: 'createUsername',
          align: 'center',
          label: '创建人'
        },
        {
          prop: 'createTime',
          align: 'center',
          type: 'slot',
          slotType: 'createTime',
          label: '创建时间'
        },
        {
          type: 'slot',
          prop: 'operation',
          label: '操作',
          width: '188',
          slotType: 'operation',
          align: 'center',
          fixed: 'right'
        }
      ],
      // 顶部表单按钮组
      options: [
        {
          type: 'button',
          icon: 'el-icon-plus',
          handler: 'handlerSave',
          float: 'left',
          btnType: 'primary',
          permission: 'create',
          text: '新增'
        },
        {
          type: 'button',
          handler: 'handlerReset',
          permission: 'list',
          float: 'right',
          class: 'infoBtn',
          text: '重置'
        },
        {
          type: 'button',
          handler: 'handlerQuery',
          permission: 'list',
          float: 'right',
          text: '查询',
          btnType: 'primary'
        },
        {
          type: 'select',
          bindValue: '',
          permission: 'list',
          float: 'right',
          label: 'keyword',
          remote,
          option: [],
          props: {
            label: 'name',
            value: 'id'
          },
          handler: 'handlerQuery',
          placeholder: '输入关键字搜索'
        }
      ],
      // 查询对象
      queryForm: {
        parentId: '0'
      },
      // 加载子节点函数map
      loadMap: {},
      // 备份初始化数据
      arr: []
    }
  },
  async created() {
    // 通过全局方法取数据字典
    this.statusList = await this.getDictInfo('dict_status')
  },
  methods: {
    // 获取列表数据
    getList(rows) {
      this.loading = true
      // 需要关键字搜索时 不从最上级开始加载，不需要时再加载最上级
      if (this.queryForm.id) {
        delete this.queryForm.parentId
      } else {
        this.queryForm.parentId = '0'
      }
      const queryForm = { ...this.queryForm }
      this.funs['list'](queryForm).then((res) => {
        if (!this.arr.length) {
          this.arr = JSON.parse(JSON.stringify(res.data)).map(item => {
            item.children = null
            return item
          })
        }
        this.data = res.data.length ? [...res.data].map(item => {
          item.isLeaf = !item.isLeaf
          item.children = null
          return item
        }) : []
        this.expanded()
        // 更新目前展开的节点
        if (rows) this.nodeRefresh(rows)
      }).finally(() => {
        this.loading = false
      })
    },
    // 展开表格树结构第一层
    expanded() {
      const els = document.getElementsByClassName('el-table__expand-icon')
      this.$nextTick(() => {
        // 检测根节点存在并为收起状态时展开
        if (els.length && els[0].classList.length === 1) els[0].click()
      })
    },
    // 加载子节点函数
    async load(tree, treeNode, resolve) {
      const res = await this.funs['list']({ parentId: tree.id })
      const data = res.data.length ? res.data.map(item => {
        item.isLeaf = !item.isLeaf
        return item
      }) : []
      // 判断父节点下无子节点，删除父节点的展开缓存，刷新父节点的父节点
      if (!data.length) {
        delete this.$refs.table.$refs.refTable.store.states.lazyTreeNodeMap[tree.id]
        this.nodeRefresh({ ...tree, ...{ endParentId: tree.parentId }})
      } else {
        this.loadMap[tree.id] = {
          tree,
          treeNode,
          resolve
        }
      }
      resolve(data)
    },
    // 查询
    handlerQuery() {
      const row = this.options.find((item) => item.type === 'select')
      this.queryForm['id'] = row.bindValue
      this.getList()
    },
    // 重置
    handlerReset() {
      this.options.find((item) => item.type === 'select').bindValue = ''
      this.queryForm = { parentId: '0' }
      this.getList()
    },
    // 节点刷新
    nodeRefresh(rows, status = true) {
      // 若对象中存在初始备份节点，需先刷新备份节点再刷新截止节点
      if (rows.startParentId && status) {
        this.nodeRefresh(rows, false)
        // 初始节点走完后需清除方便之后走入截止节点
        delete rows.startParentId
      }
      const key = rows.startParentId || rows.endParentId
      // 变量key匹配节点函数集合，若存在则走入节点刷新
      if (this.loadMap[key]) {
        const { tree, treeNode, resolve } = this.loadMap[key]
        this.load(tree, treeNode, resolve)
      }
    },
    // 状态切换触发
    switchChange(e, form) {
      form.status = e === 1 ? 2 : 1
    },
    // 确认禁用或启用
    popConfirm(form) {
      this.loading = true
      form.status = form.status === 1 ? 2 : 1
      this.funs['edit'](form).then(() => {
        if (form.status === 1) {
          this.$message.success('部门已启用')
        } else {
          this.$message.error('部门已禁用')
        }
      }).catch(e => {
        form.status = form.status === 1 ? 2 : 1
      }).finally(() => {
        this.loading = false
      })
    },
    // 行新增
    handlerRowSave(row) {
      const item = {
        parentId: row.id,
        parentName: row.name,
        sort: 0,
        status: 1
      }
      this.$refs.addOrUpdate.openDialog(item)
    }
  }
}
</script>
